package com.jia.train.seat.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.jia.train.global.enums.BusinessEnum;
import com.jia.train.global.exception.BusinessException;
import com.jia.train.global.page.PageResponse;
import com.jia.train.global.utils.SnowIdUtil;
import com.jia.train.seat.entity.DailyTripStation;
import com.jia.train.seat.entity.DailyTripStationExample;
import com.jia.train.seat.entity.TripStation;
import com.jia.train.seat.entity.TripStationExample;
import com.jia.train.seat.mapper.DailyTripStationMapper;
import com.jia.train.seat.mapper.TripStationMapper;
import com.jia.train.seat.request.DailyTripStationQueryRequest;
import com.jia.train.seat.request.DailyTripStationSaveRequest;
import com.jia.train.seat.response.DailyTripStationQueryResponse;
import com.jia.train.seat.response.DailyTripStationSaveResponse;
import com.jia.train.seat.service.DailyTripStationService;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.Duration;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class DailyTripStationServiceImpl implements DailyTripStationService {

    @Resource
    private DailyTripStationMapper dailyTripStationMapper;

    @Resource
    private TripStationMapper tripStationMapper;

    @Resource
    private TransactionTemplate transactionTemplate;

    public static final Logger logger = LoggerFactory.getLogger(DailyTripStationServiceImpl.class);


    @Override
    public DailyTripStationSaveResponse insert(DailyTripStationSaveRequest request) {
        DailyTripStation dailyTripStation
                = BeanUtil.copyProperties(request, DailyTripStation.class);
        DateTime now = DateTime.now();

        String name = request.getName();
        Date date = request.getDate();
        String tripCode = request.getTripCode();
        Integer index = request.getIndex();

        if (ObjectUtil.isNotEmpty(name)) {
            dailyTripStation.setNamePinyin(PinyinUtil.getPinyin(name, ""));
        }
        if (ObjectUtil.isEmpty(dailyTripStation.getId())) {
            dailyTripStation.setId(SnowIdUtil.getLongSnowNextId());
            dailyTripStation.setCreateTime(now);
            if (getDailyTripStationCount(date, tripCode, index) > 0 || getDailyTripStationCount(date, tripCode, name) > 0) {
                throw new BusinessException(BusinessEnum.ORDER_OF_THE_SAME_TRAIN_STATION_ALREADY_EXISTS);
            }
            // 时间处理
            LocalTime outTime = request.getOutTime();
            if (LocalTime.MIDNIGHT.equals(outTime)) {
                dailyTripStation.setStopTime(LocalTime.MIDNIGHT);
            } else {
                Duration between = Duration.between(request.getInTime(), request.getOutTime());
                dailyTripStation.setStopTime(LocalTime.MIDNIGHT.plus(between));
            }
            dailyTripStationMapper.insert(dailyTripStation);
        } else {
            dailyTripStation.setUpdateTime(now);
            dailyTripStationMapper.updateByPrimaryKeySelective(dailyTripStation);
        }

        return BeanUtil.copyProperties(dailyTripStation, DailyTripStationSaveResponse.class);
    }

    @Override
    public PageResponse<DailyTripStationQueryResponse> selectList(DailyTripStationQueryRequest request) {

        DailyTripStationExample dailyTripStationExample = new DailyTripStationExample();
        // 排序
        dailyTripStationExample.setOrderByClause("trip_code asc,`index` asc");
        //查询条件
        DailyTripStationExample.Criteria criteria = dailyTripStationExample.createCriteria();
        String tripCode = request.getTripCode();
        if (StringUtils.hasText(tripCode)) {
            criteria.andTripCodeEqualTo(tripCode);
        }
        Date date = request.getDate();
        if (ObjectUtil.isNotNull(date)) {
            criteria.andDateEqualTo(date);
        }
        // 构造分页
        PageHelper.startPage(request.getPage(), request.getSize());
        List<DailyTripStation> dailyTripStations = dailyTripStationMapper.selectByExample(dailyTripStationExample);
        PageInfo<DailyTripStation> pageInfo = new PageInfo<>(dailyTripStations);

        List<DailyTripStationQueryResponse> list
                = BeanUtil.copyToList(dailyTripStations, DailyTripStationQueryResponse.class);

        PageResponse<DailyTripStationQueryResponse> pageResponse = new PageResponse<>();
        pageResponse.setTotal(pageInfo.getTotal());
        pageResponse.setList(list);
        return pageResponse;
    }

    @Override
    public void deleteDailyTripStation(Long id) {
        dailyTripStationMapper.deleteByPrimaryKey(id);
    }

    @Override
    public void genDailyTripStation(Date date, String tripCode) {

        logger.info("生成日期：{},车次: {} 的车次车站信息", DateUtil.formatDate(date), tripCode);

        TripStationExample tripStationExample = new TripStationExample();
        tripStationExample.setOrderByClause("`index` asc");
        tripStationExample.createCriteria()
                .andTripCodeEqualTo(tripCode);
        List<TripStation> tripStations
                = tripStationMapper.selectByExample(tripStationExample);
        if (CollectionUtils.isEmpty(tripStations)) {
            logger.info("车次：{}，没有车站数据，结束生成任务", tripCode);
            return;
        }

        List<DailyTripStation> dailyTripStationList = new ArrayList<>(tripStations.size());

        for (TripStation tripStation : tripStations) {
            DailyTripStation dailyTripStation
                    = BeanUtil.copyProperties(tripStation, DailyTripStation.class);
            dailyTripStation.setId(SnowIdUtil.getLongSnowNextId());
            dailyTripStation.setCreateTime(new DateTime());
            dailyTripStation.setDate(date);
            dailyTripStationList.add(dailyTripStation);
        }

        DailyTripStationExample dailyTripStationExample = new DailyTripStationExample();
        DailyTripStationExample.Criteria criteria = dailyTripStationExample.createCriteria();
        criteria.andTripCodeEqualTo(tripCode);
        criteria.andDateEqualTo(date);

        dailyTripStationMapper.deleteByExample(dailyTripStationExample);
        dailyTripStationMapper.batchInsert(dailyTripStationList);

    }

    private long getDailyTripStationCount(Date date, String code, Integer index) {
        DailyTripStationExample dailyTripStationExample = new DailyTripStationExample();
        DailyTripStationExample.Criteria criteria = dailyTripStationExample.createCriteria();
        criteria.andDateEqualTo(date);
        criteria.andTripCodeEqualTo(code);
        criteria.andIndexEqualTo(index);
        return dailyTripStationMapper.countByExample(dailyTripStationExample);
    }

    private long getDailyTripStationCount(Date date, String code, String name) {
        DailyTripStationExample dailyTripStationExample = new DailyTripStationExample();
        DailyTripStationExample.Criteria criteria = dailyTripStationExample.createCriteria();
        criteria.andDateEqualTo(date);
        criteria.andTripCodeEqualTo(code);
        criteria.andNameEqualTo(name);
        return dailyTripStationMapper.countByExample(dailyTripStationExample);
    }
}
